import { showToast } from '@/views/ts/'
import { useWebControlsStore } from '@/store/web/controls'
import { useSiteStore } from '@/store/site'
import { defineStore, acceptHMRUpdate } from 'pinia'
import { PageAttr } from '@/store/models/web/web-default-site-style'
import { guid } from '@/utils/'
import { SiteAttrs, SiteInfo } from '@/store/models/site'
import { Card166 } from '@/store/models/web/web-card'
import { PAGE_TYPE_, ALIGN_HORIZONTAL_TYPE, ALIGN_TYPE } from '@/const/web/'
import { H5_TYPE } from '@/const';
import { SiteAttr } from '../models/web/web-default-site-style'
import { initComponentMapInPage, initSiteData, saveDealSiteData } from '@/store/utils/web/'
import { saveSiteDatasToServer, createSiteToServer } from '@/service/web/pages'
import {
  WebSitePreview,
  WebEditPathAnimate,
  WebDeleteSiteData,
  WebSiteStatus
} from '../models/web/web-site'
import { ActivityInfo } from "../activity"
import { useWebComponentStore } from './component'
import { useWebPageStore } from './page'
import { useWebUploadStore } from './upload'
import { getFileUploadData } from '@/service/web/pages'
import { recoverSiteQrcode, getSiteDataToServer, getTempPreviewUrl } from '@/service/web/user'

const deleteCompIdInComponentMap = (pageOrGroup: IGroup, componentMap: IComponentMap) => {
  const useWebComponent = useWebComponentStore()
  const useWebControls = useWebControlsStore()
  _.forEach(pageOrGroup.components, (comp: IComponent) => {
    delete componentMap[comp.id]
    useWebComponent.setActiveComponentId_()
    useWebControls.deleteControl(comp.id)
    if(comp.components && comp.components.length > 0) {
      deleteCompIdInComponentMap(comp, componentMap)
    }
  })
}
export const useWebSiteStore = defineStore('webSite', {
  state: (): IWebSiteStore => {
    return {
      id: -1,
      attrs: new SiteAttrs(),
      allPageMap: {},
      componentMap: {},
      pages: [], //all pages
      sitePreview: new WebSitePreview(),
      siteInfo: new SiteInfo(),
      siteStatus: new WebSiteStatus(),
      editPathAnimate: new WebEditPathAnimate(),
      deleteSiteData: new WebDeleteSiteData(),
      siteTempPreviewItem: null,
      activityInfo: new ActivityInfo(),
      siteData: {},
      siteDatas: {},
      position: {
        left: 0,
        top: 0
      },
      isResiterComp: false
    }
  },
  getters: {
    isSwiper: () => {
      return false
    },
    getH5Pages(): IPage[] {
      return _.filter(this.pages, function (o: IPage) { return o && o.type == PAGE_TYPE_.page })
    },
    getPopPages(): IPage[] {
      return _.filter(this.pages, function (o: IPage) { return o.type == PAGE_TYPE_.pop })
    },
  },
  actions: {
    updateResiterComp(isResiterComp: boolean) {
      this.isResiterComp = isResiterComp
    },
    setIsEdit(data: boolean) {
      this.siteStatus.isEdit = data
    },
    clearShiftComponents() {
      while (this.siteStatus.shiftComponents.length > 0) {
        this.siteStatus.shiftComponents.pop()
      }
    },
    alignComponents(type: number) {
      let minTop = 0
      let maxTop = 0
      let maxBottom = 0
      let minLeft = 0
      let maxLeft = 0
      let maxRight = 0
      // let minRight = 0
      let maxHeight = 0
      // let minHeight = 0
      let maxWidth = 0
      // let minWidth = 0
      let distance = 0
      let allHeight = 0
      let allWidth = 0

      let tops: number[] = []
      let bottoms: number[] = []
      let lefts: number[] = []
      let rights: number[] = []
      let heights: number[] = []
      let widths: number[] = []
      let shiftComponents = this.siteStatus.shiftComponents

      if (ALIGN_HORIZONTAL_TYPE.indexOf(type) != -1) {
        shiftComponents = _.sortBy(shiftComponents, (componentData) => {
          return componentData.conAttr.left
        })
      } else {
        shiftComponents = _.sortBy(shiftComponents, (componentData) => {
          return componentData.conAttr.top
        })
      }

      let len = shiftComponents.length - 1
      _.forEach(shiftComponents, (componentData: IComponent, index) => {
        let conAttr = componentData.conAttr
        tops.push(conAttr.top)
        bottoms.push(conAttr.top + conAttr.height)
        lefts.push(conAttr.left)
        rights.push(conAttr.left + conAttr.width)
        heights.push(conAttr.height)
        widths.push(conAttr.width)
        if (index != len) {
          allHeight += conAttr.height
          allWidth += conAttr.width
        }
      })
      minTop = _.min(tops)
      maxTop = _.max(tops)
      maxBottom = _.max(bottoms)
      maxLeft = _.max(lefts)
      minLeft = _.min(lefts)
      maxRight = _.max(rights)
      // minRight = _.min(rights)
      maxHeight = _.max(heights)
      // minHeight = _.min(heights)
      maxWidth = _.max(widths)
      // minWidth = _.min(widths)

      if (ALIGN_HORIZONTAL_TYPE.indexOf(type) != -1) {
        distance = (maxLeft - minLeft - allWidth) / len
      } else {
        distance = (maxTop - minTop - allHeight) / len
      }

      _.forEach(shiftComponents, (componentData: IComponent, index: number) => {
        if (ALIGN_TYPE.top == type) {
          componentData.conAttr.top = minTop
        } else if (ALIGN_TYPE.bottom == type) {
          componentData.conAttr.top = maxBottom - componentData.conAttr.height
        } else if (ALIGN_TYPE.left == type) {
          componentData.conAttr.left = minLeft
        } else if (ALIGN_TYPE.right == type) {
          componentData.conAttr.left = maxRight - componentData.conAttr.width
        } else if (ALIGN_TYPE.horizontalCenterAlign == type) {
          componentData.conAttr.top = minTop + maxHeight / 2 - componentData.conAttr.height / 2
        } else if (ALIGN_TYPE.horizontalCenterDistribute == type) {
          if (index > 0) {
            let comp = shiftComponents[index - 1]
            componentData.conAttr.left = comp.conAttr.left + comp.conAttr.width + distance
          }
        } else if (ALIGN_TYPE.verticalCenterAlign == type) {
          componentData.conAttr.left = minLeft + (maxWidth) / 2 - componentData.conAttr.width / 2
        } else if (ALIGN_TYPE.verticalCenterDistribute == type) {
          if (index > 0) {
            let comp = shiftComponents[index - 1]
            componentData.conAttr.top = comp.conAttr.top + comp.conAttr.height + distance
          }
        }
      })
    },
    updateKeyDownShift(isShift: boolean) {
      this.siteStatus.isShift = isShift
    },
    updateShiftComponents(isShift: boolean) {
      const useWebComponent = useWebComponentStore()
      let currentComponentData = useWebComponent.currentComponentData
      if (isShift && currentComponentData) {
        if (this.siteStatus.shiftComponents.indexOf(currentComponentData) == -1) {
          this.siteStatus.shiftComponents.push(currentComponentData)
        }
      }
    },
    updateSiteAttrs(attrs: ISiteAttrs | any) {
      _.merge(this.attrs, attrs)
    },
    updateDeleteSiteData({ isDelete, site_id }: { isDelete: boolean, site_id: string }) {
      this.deleteSiteData.isDelete = isDelete
      this.deleteSiteData.site_id = site_id
    },
    // 对siteData的处理
    updateOtherSettingShare(data: IShareAttr | any) {
      (this.siteData as IWebSiteStore).attrs.share = _.cloneDeep(data)
      _.assign((this.siteData as IWebSiteStore).attrs.share, data)
    },
    setSitePreview(sitePreview: IWebSitePreview) {
      _.merge(this.sitePreview, sitePreview)
    },
    setTempPreviewUrl(data: IWebSiteTempPreviewItem) {
      this.siteTempPreviewItem = data
    },
    updateSettingShare(data: IShareAttr) {
      _.merge(this.attrs.share, data)
    },
    removeShiftComponents() {
      const useWebPage = useWebPageStore()
      _.pullAll(useWebPage.currentPage!.components, this.siteStatus.shiftComponents);
      while (this.siteStatus.shiftComponents.length > 0) {
        this.siteStatus.shiftComponents.pop();
      }
    },
    updateSiteScale(data: number) {
      this.siteStatus.scale = data;
    },
    updateSiteStatus(data: IWebSiteStatus) {
      _.merge(this.siteStatus, data)
      if (this.siteStatus.isHighComponentConfiguration) {
        localStorage.isHighComponentConfiguration = true
      }
    },
    addPage(type: number) {
      const page: IPage = _.cloneDeep(PageAttr)
      page.type = type
      page.isActive = false
      page.id = guid()
      this.addPages_(page)
      const useWebComponent = useWebComponentStore()
      useWebComponent.setActiveComponentId()
      const useWebPage = useWebPageStore()
      useWebPage.setActivePage(page)
    },
    addPages_(page: IPage) {
      const useWebPage = useWebPageStore()
      this.pages.push(page)
      useWebPage.currentPage = page
    },
    deletePage(id: string) {
      const page = this.pages.find(page => page.id == id)
      if(page) {
        deleteCompIdInComponentMap(page, this.componentMap)
      }
      const pageIndex = this.pages.findIndex(page => page.id == id)
      this.pages.splice(pageIndex, 1)
    },
    createSite({ type, $router, siteData }) {
      const useWebPage = useWebPageStore()
      const useWebControls = useWebControlsStore()
      const params = { id: "", tag: type }
      createSiteToServer(params, (data: IWebSiteData_) => {
        if(siteData) {
          siteData.id = data.id
          data = siteData
          if(siteData.controls) {
            useWebControls.setControls(siteData.controls)
          }
        }
        
        this.setSiteDatas(data)
        useWebPage.setActivePage(this.pages[0])
        useWebPage.setCurrentPageOrPopIndex(0, -1)
        $router.push({ path: `/h5edit/${data.id}`})
        window.setTimeout(() => {
          const controls = siteData && siteData.controls ? siteData.controls : {}
          const data = saveDealSiteData(controls, _.cloneDeep(this.$state))
          saveSiteDatasToServer(data, () => {
            this.savePageDatas_()
          })
        }, 50)
      })
    },
    recoverSiteQrcode({site_id}){
      recoverSiteQrcode({site_id}, (data: any) => {
        this.recoverSiteQrcode_(data)
      })
    },
    recoverSiteQrcode_(data:any) {
      //online 2-下线，1-上线
      let qrData = data[(this.siteData as IWebSiteStore).id]
      this.siteTempPreviewItem!.qrcode = this.siteTempPreviewItem!.status == 1 ? qrData.online : qrData.tmp
    },
    getSiteDatas({item, isTempPreviewUrl, callback}: {item: IWebSiteItem, isTempPreviewUrl: any, callback?: any }) {
      const useWebPage = useWebPageStore()
      const useWebUpload= useWebUploadStore()

      const dealSiteData = (data_: IWebSiteData_) => {
        if(callback) {
          callback(data_)
        } else {
          const siteStatus = this.siteStatus
          const componentFrontAttr = useWebPage.componentFrontAttr
          const fileUploadData = useWebUpload.fileUploadData
          if (data_.attrs && data_.attrs.h5Type != H5_TYPE.card) {
            this.setSiteData(initSiteData(data_, siteStatus, componentFrontAttr, fileUploadData))
          }
          if(isTempPreviewUrl) {
            getTempPreviewUrl({ site_id: item.site_id }, (data: IWebSiteTempPreviewItem) => {
              this.setSitePreview({isActive: true})
              this.setTempPreviewUrl(data)
            })
          }
        }
      }
      if(!this.siteDatas[item.site_id]) {
        getSiteDataToServer({ id: item.site_id }, (data: IWebSiteData_) => {
          dealSiteData(data)
        })
      } else {
        dealSiteData(this.siteDatas[item.site_id])
      }
    },
    getSiteData(id: number) {
      const useWebUpload = useWebUploadStore()
      if (!useWebUpload.fileUploadData.uid) {
        getFileUploadData((data: IFileUploadData) => {
          useWebUpload.setFileUploadData(data)
        })
      }
      getSiteDataToServer({ id }, (data: IWebSiteData_) => {
        data.id = id
        this.setSiteDatas(data)
        const useWebPage = useWebPageStore()
        useWebPage.setActivePage(this.pages[0])
        useWebPage.setCurrentPageOrPopIndex(0, -1)
        const controls = data.controls
        delete data.controls
        const useWebControls = useWebControlsStore()
        useWebControls.setControls(controls)
        useWebControls.setActiveWbData(useWebPage.currentPage)
      })
    },
    setSiteDatas(data: IWebSiteData_) {
      const useWebPage = useWebPageStore()
      const useWebComponent = useWebComponentStore()
      const useWebUpload = useWebUploadStore()
      this.pages = []
      useWebPage.currentPage = null
      useWebComponent.currentComponentData = null
      this.id = -1
      this.attrs = _.cloneDeep(SiteAttr.attrs)
      const siteStatus = this.siteStatus
      const componentFrontAttr = useWebPage.componentFrontAttr
      const fileUploadData = useWebUpload.fileUploadData
      // 编辑端与移动端公用 componentMap
      this.componentMap = {}
      useSiteStore().componentMap = this.componentMap
      initComponentMapInPage(this.componentMap, data.pages!)
      const siteData = initSiteData(data as IWebSiteData_, siteStatus, componentFrontAttr, fileUploadData)
      _.merge(this.$state, siteData)
    },
    saveSiteDatas(cb?: Function) {
      const useWebControls = useWebControlsStore()
      const controls = _.cloneDeep(useWebControls.controls)
      const siteData = saveDealSiteData(controls, _.cloneDeep(this.$state))
      saveSiteDatasToServer(siteData, () => {
        this.savePageDatas_()
        if (cb) cb()
      });
    },
    savePageDatas_() {
      this.siteStatus.loading = false
      showToast('站点保存成功')
    },
    setLocalData(data: any) {
      this.setSiteDatas(data)
      const useWebPage = useWebPageStore()
      useWebPage.setActivePage(this.pages[0])
      useWebPage.setCurrentPageOrPopIndex(0, -1)
      const useWebControls = useWebControlsStore()
      useWebControls.setControls(data.controls)
    },
    setSiteData(data: IWebSiteData_){
      this.siteData = data
      this.siteDatas[data.id] = data
    },
    createCardAttrs() {
      this.attrs.share.card166 = _.clone(Card166)
    },
    updateCardAttrs(card166: ICard166) {
      _.merge(this.attrs.share.card166, card166)
    }
  },
})

if (import.meta.hot) {
  import.meta.hot!.accept(acceptHMRUpdate(useWebSiteStore, import.meta.hot))
}